from textwrap import dedent
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QTextEdit, 
                                    QLineEdit, QPushButton, QHBoxLayout,
                                    QSplitter, QMessageBox)
from PyQt6.QtCore import Qt, QTimer
from PyQt6.QtGui import QTextCharFormat, QColor, QTextCursor
import asyncio
import json
from logger import logger

system_PROMPT = dedent("""\
    You are an elite software engineer called DeepSeek Engineer with decades of experience across all programming domains.
    Your expertise spans system design, algorithms, testing, and best practices.
    You provide thoughtful, well-structured solutions while explaining your reasoning.

    Core capabilities:
    1. Code Analysis & Discussion
       - Analyze code with expert-level insight
       - Explain complex concepts clearly
       - Suggest optimizations and best practices
       - Debug issues with precision

    2. File Operations:
       a) Read existing files
          - Access user-provided file contents for context
          - Analyze multiple files to understand project structure
       
       b) Create new files
          - Generate complete new files with proper structure
          - Create complementary files (tests, configs, etc.)
       
       c) Edit existing files
          - Make precise changes using diff-based editing
          - Modify specific sections while preserving context
          - Suggest refactoring improvements

    Output Format:
    You must provide responses in this JSON structure:
    {
      "assistant_reply": "Your main explanation or response",
      "files_to_create": [
        {
          "path": "path/to/new/file",
          "content": "complete file content"
        }
      ],
      "files_to_edit": [
        {
          "path": "path/to/existing/file",
          "original_snippet": "exact code to be replaced",
          "new_snippet": "new code to insert"
        }
      ]
    }

    Guidelines:
    1. YOU ONLY RETURN JSON, NO OTHER TEXT OR EXPLANATION OUTSIDE THE JSON!!!
    2. For normal responses, use 'assistant_reply'
    3. When creating files, include full content in 'files_to_create'
    4. For editing files:
       - Use 'files_to_edit' for precise changes
       - Include enough context in original_snippet to locate the change
       - Ensure new_snippet maintains proper indentation
       - Prefer targeted edits over full file replacements
    5. Always explain your changes and reasoning
    6. Consider edge cases and potential impacts
    7. Follow language-specific best practices
    8. Suggest tests or validation steps when appropriate

    Remember: You're a senior engineer - be thorough, precise, and thoughtful in your solutions.
""")

class ChatPanel(QWidget):
    def __init__(self, ai_service, parent=None):
        super().__init__(parent)
        self.ai_service = ai_service
        self.conversation_history = [
            {"role": "system", "content": system_PROMPT}
        ]
        self.loop = asyncio.get_event_loop()
        logger.info("初始化聊天面板")
        self.init_ui()

    def init_ui(self):
        layout = QVBoxLayout(self)
        
        # 对话历史区域
        self.chat_history = QTextEdit()
        self.chat_history.setReadOnly(True)
        
        # 创建底部输入区域
        input_layout = QHBoxLayout()
        
        # 输入框
        self.input_edit = QLineEdit()
        self.input_edit.setPlaceholderText("在此输入消息...")
        self.input_edit.returnPressed.connect(self.send_message)
        
        # 发送按钮
        self.send_button = QPushButton("发送")
        self.send_button.clicked.connect(self.send_message)
        
        # 添加到输入布局
        input_layout.addWidget(self.input_edit)
        input_layout.addWidget(self.send_button)
        
        # 添加所有组件到主布局
        layout.addWidget(self.chat_history)
        layout.addLayout(input_layout)
        
    def append_message(self, text, is_user=True):
        """添加消息到聊天历史"""
        cursor = self.chat_history.textCursor()
        cursor.movePosition(QTextCursor.MoveOperation.End)
        
        # 创建格式
        format = QTextCharFormat()
        if is_user:
            format.setForeground(QColor("#2979FF"))  # 用户消息使用蓝色
            prefix = "You: "
        else:
            format.setForeground(QColor("#2E7D32"))  # AI消息使用绿色
            prefix = "AI: "
        
        # 插入前缀
        cursor.insertText(prefix, format)
        
        # 插入消息内容
        format.setForeground(QColor("black"))
        cursor.insertText(text + "\n", format)
        
        # 滚动到底部
        self.chat_history.verticalScrollBar().setValue(
            self.chat_history.verticalScrollBar().maximum()
        )
    
    def show_reasoning(self, text):
        """在对话历史中显示推理过程"""
        if not text or not text.strip():  # 跳过空内容
            return
            
        cursor = self.chat_history.textCursor()
        cursor.movePosition(QTextCursor.MoveOperation.End)
        
        format = QTextCharFormat()
        format.setForeground(QColor("#9E9E9E"))  # 使用灰色显示推理过程
        
        # 先清除之前的推理内容
        self.chat_history.moveCursor(QTextCursor.MoveOperation.End)
        cursor = self.chat_history.textCursor()
        cursor.movePosition(QTextCursor.MoveOperation.StartOfBlock, QTextCursor.MoveMode.KeepAnchor)
        if cursor.selectedText().startswith("Reasoning:"):
            cursor.removeSelectedText()
            
        # 显示新的推理内容
        cursor.movePosition(QTextCursor.MoveOperation.End)
        cursor.insertText("Reasoning: " + text + "\n", format)
        
        self.chat_history.verticalScrollBar().setValue(
            self.chat_history.verticalScrollBar().maximum()
        )
    
    def send_message(self):
        """发送消息"""
        text = self.input_edit.text().strip()
        if not text:
            return
            
        logger.info(f"用户发送消息: {text[:100]}...")
            
        # 显示用户消息
        self.append_message(text, is_user=True)
        
        # 清空输入框
        self.input_edit.clear()
        
        # 禁用输入区域
        self.input_edit.setEnabled(False)
        self.send_button.setEnabled(False)
        
        # 在事件循环中运行异步任务
        self.loop.create_task(self.handle_ai_response(text))
            
    async def handle_ai_response(self, message):
        """处理AI响应"""
        try:
            logger.info("开始处理AI响应")
            response = await self.ai_service.send_message(
                message,
                self.conversation_history,
                self.show_reasoning
            )
            
            if response:
                parsed_response = json.loads(response)
                if "assistant_reply" in parsed_response and parsed_response["assistant_reply"]:
                    self.append_message(parsed_response["assistant_reply"], is_user=False)
                    self.conversation_history.append({
                        "role": "assistant",
                        "content": response
                    })

        except Exception as e:
            error_msg = f"发送消息时出错: {str(e)}"
            logger.error(error_msg)
            QMessageBox.critical(
                self,
                "错误",
                error_msg
            )
            
        finally:
            # 重新启用输入区域
            self.input_edit.setEnabled(True)
            self.send_button.setEnabled(True)
            
    def clear_all(self):
        """清空所有区域"""
        logger.info("清空所有聊天区域")
        self.chat_history.clear()
        self.input_edit.clear()
        self.conversation_history.clear()
        self.conversation_history.append({"role": "system", "content": system_PROMPT})
